
#include "flash.h"

#include <stdio.h>
#include <string.h>
#include "main.h"
#include "usart.h"
#include "CH9120.h"

extern uint8_t Dest_IP[16];
extern uint8_t Dest_PORT[6];
extern uint8_t CH9120_Dest_IP[4];
extern uint16_t CH9120_Dest_PORT;

extern uint8_t CH9120_DHCP;

extern uint8_t CH9120_Local_IP[4]; 
extern uint8_t CH9120_Local_GW[4];
extern uint8_t CH9120_Local_MASK[4];


uint32_t addr = 0x0800e000; 

static FLASH_EraseInitTypeDef EraseInitStruct = {
	.TypeErase = FLASH_TYPEERASE_PAGES,
	.PageAddress = 0x0800e000,
	.NbPages = 1
};

uint8_t Read_Config(void)
{
	uint32_t readFlashData;
	uint8_t Config_Data[32];
	uint8_t i,j,k;

	uint16_t ip_begin,ip_end,port_begin,port_end;
	uint8_t len;
	uint8_t Read_Dest_IP[16];
	uint8_t Read_Dest_PORT[6];
	uint8_t Read_CH9120_Dest_IP[4];
	uint16_t Read_CH9120_Dest_PORT;

	HAL_FLASH_Unlock();
	for(i=0;i<16;i++)
	{
		readFlashData = *(__IO uint32_t*)(addr+(i<<2));
		Config_Data[4*i+3] = readFlashData>>24;
		Config_Data[4*i+2] = readFlashData>>16;
		Config_Data[4*i+1] = readFlashData>>8;
		Config_Data[4*i+0] = readFlashData;
	}
	SysPrintf("read config data:");
	for(i=0;i<32;i++)
	{
		SysPrintf("%x",Config_Data[i]);
	}
	SysPrintf("\r\n");
	
	HAL_FLASH_Lock();
	/*
	
	SysPrintf("read CH9120 DHCP config para\r\n");
	if(Config_Data[32]==0x01) 
	{
		CH9120_DHCP = CH9120_DHCP_ENABLE;
		SysPrintf("CH9120 DHCP ENABLE\r\n");
	}
	else 
	{
		CH9120_DHCP = CH9120_DHCP_DISABLE;
		SysPrintf("CH9120 DHCP DISABLE\r\n");
	}
	
	
	if((Config_Data[36]==0) || (Config_Data[36]==0xff)) 
	{
		SysPrintf("eth0 local ip not configed and use default...\r\n");
		SysPrintf("default local ip:%d.%d.%d.%d\r\n",CH9120_Local_IP[0],CH9120_Local_IP[1],CH9120_Local_IP[2],CH9120_Local_IP[3]);	
	}
	else
	{
		CH9120_Local_IP[0] = Config_Data[36];
		CH9120_Local_IP[1] = Config_Data[37];
		CH9120_Local_IP[2] = Config_Data[38];
		CH9120_Local_IP[3] = Config_Data[39];
		SysPrintf("configed local ip:%d.%d.%d.%d\r\n",CH9120_Local_IP[0],CH9120_Local_IP[1],CH9120_Local_IP[2],CH9120_Local_IP[3]);
	}
	
	if((Config_Data[40]==0) || (Config_Data[40]==0xff)) 
	{
		SysPrintf("eth0 local gw not configed and use default...\r\n");
		SysPrintf("default local gw:%d.%d.%d.%d\r\n",CH9120_Local_GW[0],CH9120_Local_GW[1],CH9120_Local_GW[2],CH9120_Local_GW[3]);
	}
	else
	{
		CH9120_Local_GW[0] = Config_Data[40];
		CH9120_Local_GW[1] = Config_Data[41];
		CH9120_Local_GW[2] = Config_Data[42];
		CH9120_Local_GW[3] = Config_Data[43];
		SysPrintf("configed local gw:%d.%d.%d.%d\r\n",CH9120_Local_GW[0],CH9120_Local_GW[1],CH9120_Local_GW[2],CH9120_Local_GW[3]);
	}
	
	
	if((Config_Data[44]==0) || (Config_Data[44]==0xff)) 
	{
		SysPrintf("eth0 local mask not configed and use default...\r\n");
		SysPrintf("default local mask:%d.%d.%d.%d\r\n",CH9120_Local_MASK[0],CH9120_Local_MASK[1],CH9120_Local_MASK[2],CH9120_Local_MASK[3]);
	}
	else
	{
		CH9120_Local_MASK[0] = Config_Data[44];
		CH9120_Local_MASK[1] = Config_Data[45];
		CH9120_Local_MASK[2] = Config_Data[46];
		CH9120_Local_MASK[3] = Config_Data[47];
		SysPrintf("configed local mask:%d.%d.%d.%d\r\n",CH9120_Local_MASK[0],CH9120_Local_MASK[1],CH9120_Local_MASK[2],CH9120_Local_MASK[3]);
	}
	
	
	
	*/
	
	
	
	if( (strstr(Config_Data,":")!=NULL) && (strstr(Config_Data,"AA")!=NULL) )
	{

		for(i=0;i<32;i++)
		{
			if( Config_Data[i]==':')
			{
				ip_begin = 0;
				ip_end = i-1;
				break;
			}
		}
		if(i==32)
		{
			SysPrintf("read config dest ip format err\r\n");
		}
			
		for(i=ip_end;i<32;i++)
		{
			if( (Config_Data[i-1]=='A') && (Config_Data[i]=='A'))
			{
				port_begin = ip_end + 2;
				port_end = i-2;
				break;
			}
		}
		if(i==32)
		{
			SysPrintf("read config port format err\r\n");
		}
			
		j = 0;
		for(i=ip_begin;i<=port_end;i++)
		{
			if(Config_Data[i]=='.')
				j++;
		}
		if(j!=3)
		{
			SysPrintf("read config dest ipport format err\r\n");
			return 0;
		}
			
		for(i=0;i<ip_end-ip_begin+1;i++)
		{
			Read_Dest_IP[i] = Config_Data[i+ip_begin];
		}
		for(i=ip_end-ip_begin+1;i<32;i++)
		{
			Read_Dest_IP[i] = 0;
		}
		SysPrintf("read config ip:%s\r\n",Read_Dest_IP);
			
		for(i=0;i<port_end-port_begin+1;i++)
		{
			Read_Dest_PORT[i] = Config_Data[i+port_begin];
		}
		for(i=port_end-port_begin+1;i<6;i++)
		{
			Read_Dest_PORT[i] = 0;
		}
			
			SysPrintf("read config port:%s\r\n",Read_Dest_PORT);
			
			
			for(i=0;i<4;i++)
				Read_CH9120_Dest_IP[i] = 0;
			Read_CH9120_Dest_PORT = 0;
			
			k = ip_begin;
			for(i=k;i<k+4;i++)
			{
				if(Config_Data[i]=='.')
				{
					len = i - k;
					j = k;					
					while(len--)
					{
						Read_CH9120_Dest_IP[0] = Read_CH9120_Dest_IP[0]*10 + (Config_Data[j]-'0');
						j++;
					}
					k = i + 1;
					break;
				}
			}
			
			for(i=k;i<k+4;i++)
			{
				if(Config_Data[i]=='.')
				{
					len = i - k;
					j = k;					
					while(len--)
					{
						Read_CH9120_Dest_IP[1] = Read_CH9120_Dest_IP[1]*10 + (Config_Data[j]-'0');
						j++;
					}
					k = i + 1;
					break;
				}
			}
			
			for(i=k;i<k+4;i++)
			{
				if(Config_Data[i]=='.')
				{
					len = i - k;
					j = k;					
					while(len--)
					{
						Read_CH9120_Dest_IP[2] = Read_CH9120_Dest_IP[2]*10 + (Config_Data[j]-'0');
						j++;
					}
					k = i + 1;
					break;
				}
			}
			
			for(i=k;i<k+4;i++)
			{
				if(Config_Data[i]==':')
				{
					len = i - k;
					j = k;					
					while(len--)
					{
						Read_CH9120_Dest_IP[3] = Read_CH9120_Dest_IP[3]*10 + (Config_Data[j]-'0');
						j++;
					}
					k = i + 1;
					break;
				}
			}
			
			len = port_end - port_begin + 1;
			j = port_begin;
			while(len--)
			{
				Read_CH9120_Dest_PORT = Read_CH9120_Dest_PORT*10 +  (Config_Data[j]-'0');
				j++;
			}
			
			SysPrintf("compute 9120 ipport:%d.%d.%d.%d:%d\r\n",Read_CH9120_Dest_IP[0],Read_CH9120_Dest_IP[1],Read_CH9120_Dest_IP[2],Read_CH9120_Dest_IP[3],Read_CH9120_Dest_PORT);
			
			for(i=0;i<16;i++)
				Dest_IP[i] = Read_Dest_IP[i];
			
			for(i=0;i<6;i++)
				Dest_PORT[i] = Read_Dest_PORT[i];
			
			for(i=0;i<4;i++)
				CH9120_Dest_IP[i] = Read_CH9120_Dest_IP[i];
			
			CH9120_Dest_PORT = Read_CH9120_Dest_PORT;

		return 1;
		
	}
	else
	{
		SysPrintf("read config-info err\r\n");
		return 0;
	}
}
	


uint8_t Write_Config(uint8_t *buf,uint8_t len)
{
	uint32_t PageError = 0;
	uint32_t writeFlashData[8];
	uint8_t i = 0;
	uint8_t Config_Data[32];
	SysPrintf("write config data to flash begin\r\n");
	if(len<32)
	{
		for(i=0;i<len;i++)
			Config_Data[i] = buf[i];
		for(i=len;i<32;i++)
			Config_Data[i] = 0;
	}
	else
	{
		SysPrintf("length err\r\n");
		return 0;
	}
		
	if(Check_Config_Data(buf,len)==1)
	{
		HAL_FLASH_Unlock();
		if (HAL_FLASHEx_Erase(&EraseInitStruct,&PageError) == HAL_OK)
		{
			SysPrintf("Erase page success\r\n");
		}
		for(i=0;i<sizeof(Config_Data);i+=4)
		{
			HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,addr+i,*(uint32_t*)(Config_Data+i));
		}
		HAL_FLASH_Lock();
		SysPrintf("write config data to flash end sys will reboot.......\r\n");
		NVIC_SystemReset();
		return 1;
	}
	else
	{
		SysPrintf("format err not write flash\r\n");
		return 0;
	}
}


uint8_t Check_Config_Data(uint8_t *buf,uint8_t len)
{
	uint16_t i,j,k;
	SysPrintf("check recv cmd format\r\n");
	j = 0;
	if((strstr(buf,":")!=NULL) && (strstr(buf,"AA")!=NULL))
	{
		
		for(i=0;i<=len;i++)
		{
			if(buf[i]=='.')
				j++;
		}
		if(j!=3)
		{
			SysPrintf("config ipport format err1\r\n");
			return 0;
		}

		if( (buf[len-2]=='A') && (buf[len-1]=='A') )
		{
			;
		}
		else
		{
			SysPrintf("config ipport format err2\r\n");
			return 0;
		}
		
		for(i=0;i<len-2;i++)
		{
			if( (buf[i]=='.') || (buf[i]==':') || ((buf[i]<='9') && (buf[i]>='0')) )
			{
				;
			}
			else
			{
				SysPrintf("config ipport format err3\r\n");
				return 0;
			}
		}
		return 1;
		
	}
	else
	{
		SysPrintf("length err\r\n");
		return 0;
	}
}	


